<script setup>
import { ref } from 'vue';
import axios from 'axios';
import { onMounted } from 'vue';
import { marked } from 'marked';
import DOMPurify from 'dompurify';

// 配置marked选项
marked.setOptions({
  breaks: true,   // 将换行符转换为<br>
  gfm: true,      // 使用GitHub风格的Markdown
});

const imageUrl = ref('');
const textInput = ref('Describe this image');
const apiResponse = ref('');
const isLoading = ref(false);
const errorMessage = ref('');

// 用于存储上传的图片文件
const uploadedFile = ref(null);

const handleImageUpload = (event) => {
  const file = event.target.files[0];
  if (file) {
    uploadedFile.value = file; // 保存文件引用
    const reader = new FileReader();
    reader.onload = (e) => {
      imageUrl.value = e.target.result; // 这是用于预览的Base64
    };
    reader.readAsDataURL(file);
  }
};

// 将Base64转换为Blob对象
const base64ToBlob = (base64Data) => {
  // 移除Base64前缀（如data:image/jpeg;base64,）
  const base64WithoutPrefix = base64Data.includes('base64,') 
    ? base64Data.split('base64,')[1] 
    : base64Data;
  
  // 解码Base64
  const binaryString = window.atob(base64WithoutPrefix);
  const bytes = new Uint8Array(binaryString.length);
  
  for (let i = 0; i < binaryString.length; i++) {
    bytes[i] = binaryString.charCodeAt(i);
  }
  
  // 从类型中提取MIME类型
  let mimeType = 'image/jpeg'; // 默认
  if (base64Data.includes('data:')) {
    mimeType = base64Data.split(';')[0].split(':')[1];
  }
  
  return new Blob([bytes], { type: mimeType });
};

const analyzeImage = async () => {
  if (!imageUrl.value) {
    errorMessage.value = '请先上传图片';
    return;
  }
  
  try {
    isLoading.value = true;
    errorMessage.value = '';
    
    // 直接使用图片URL，包括Base64格式
    const finalImageUrl = imageUrl.value;
    
    // 如果是Base64编码的图片，记录日志
    if (imageUrl.value.startsWith('data:')) {
      console.log('使用Base64编码的图片数据');
    }
    
    // 构建请求参数
    const payload = {
      messages: [
        {
          role: 'user',
          content: [
            {
              type: 'image_url',
              image_url: {
                url: finalImageUrl
              }
            },
            {
              type: 'text',
              text: textInput.value
            }
          ]
        }
      ],
      metadata: {
        enable_thinking: false
      }
    };
    
    console.log('发送请求:', payload);
    
    // 发送API请求 - 使用代理路径避免CORS问题
    const response = await axios.post('/api/v1/chat/completions', payload);
    apiResponse.value = response.data;
  } catch (error) {
    console.error('API调用失败:', error);
    errorMessage.value = `API调用失败: ${error.message}`;
  } finally {
    isLoading.value = false;
  }
};

// 提供一个示例图片URL
const useExampleImage = () => {
  imageUrl.value = 'https://paddlenlp.bj.bcebos.com/datasets/paddlemix/demo_images/example2.jpg';
};
</script>

<template>
  <div class="image-analyzer">
    <h1>智能图像分析系统</h1>
    
    <div class="input-section">
      <div class="image-section">
        <h3>图片上传区域</h3>
        <div class="image-preview" v-if="imageUrl">
          <img :src="imageUrl" alt="已上传图片" />
          <div class="image-info">图片已成功加载</div>
        </div>
        <div class="image-upload" v-else>
          <div class="upload-placeholder">
            <i class="upload-icon">📷</i>
            <div class="upload-title">拖放图片到此处或点击下方按钮上传</div>
            <div class="upload-hint">支持JPG、PNG、WEBP等常见图片格式</div>
          </div>
        </div>
        
        <div class="image-controls">
          <input type="file" accept="image/*" @change="handleImageUpload" id="image-upload" />
          <label for="image-upload" class="btn">
            <span class="btn-icon">📂</span> 选择本地图片
          </label>
          <button @click="useExampleImage" class="btn">
            <span class="btn-icon">🖼️</span> 使用示例图片
          </button>
        </div>
      </div>
      
      <div class="text-section">
        <h3>分析提示文本</h3>
        <textarea 
          v-model="textInput" 
          placeholder="请输入分析要求..."
        ></textarea>
        <div class="text-hint">
          <span class="message-icon info-icon">💡</span>
          提示：详细、明确的问题可以获得更准确的分析结果
        </div>
      </div>
    </div>
    
    <div class="action-section">
      <button @click="analyzeImage" class="btn primary" :disabled="isLoading">
        <span class="btn-icon" v-if="!isLoading">🔍</span>
        <span v-if="isLoading" class="loading-spinner"></span>
        {{ isLoading ? '正在分析中...' : '开始智能分析' }}
      </button>
      <div class="message-container">
        <p class="error" v-if="errorMessage && errorMessage.includes('失败')">
          <span class="message-icon">❌</span> {{ errorMessage }}
        </p>
        <p class="warning" v-else-if="errorMessage">
          <span class="message-icon">⚠️</span> {{ errorMessage }}
        </p>
      </div>
    </div>
    
    <div class="result-section" v-if="apiResponse">
      <h3>分析结果</h3>
      <div class="result-content">
        <div v-if="apiResponse.choices && apiResponse.choices.length > 0">
          <div class="response-text">
            <h4><span class="result-icon">🤖</span> AI智能分析结果:</h4>
            <div class="markdown-content" v-html="apiResponse.choices[0].message?.content ? DOMPurify.sanitize(marked.parse(apiResponse.choices[0].message.content)) : '无内容'"></div>
          </div>
          <div class="response-details">
            <h4><span class="result-icon">📊</span> 技术详细信息:</h4>
            <div class="json-toggle">
              <pre>{{ JSON.stringify(apiResponse, null, 2) }}</pre>
            </div>
          </div>
        </div>
        <div v-else>
          <div class="response-text">
            <h4><span class="result-icon">📋</span> API原始响应:</h4>
            <pre>{{ JSON.stringify(apiResponse, null, 2) }}</pre>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.image-analyzer {
  width: 100%;
  margin: 0 auto;
  padding: 30px 40px;
  background-color: #ffffff;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
}

.image-analyzer h1 {
  font-size: 30px;
  text-align: center;
  margin-bottom: 35px;
  color: #2c3e50;
  font-weight: 700;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  position: relative;
  display: inline-block;
  padding: 0 20px;
  margin-left: auto;
  margin-right: auto;
}

.image-analyzer h1::after {
  content: '';
  position: absolute;
  bottom: -10px;
  left: 50%;
  transform: translateX(-50%);
  width: 80px;
  height: 4px;
  background-color: #42b883;
  border-radius: 2px;
}

.input-section {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 30px;
  margin-bottom: 35px;
  background-color: #f8fafc;
  padding: 35px;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  border: 1px solid #eaeef2;
}

@media (max-width: 1200px) {
  .input-section {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .image-analyzer {
    padding: 20px 15px;
  }
  
  .image-analyzer h1 {
    font-size: 24px;
  }
}

.image-section, .text-section {
  width: 100%;
}

.image-section h3, .text-section h3 {
  font-size: 20px;
  color: #2c3e50;
  margin-top: 0;
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: 2px solid #e0e6ed;
  font-weight: 600;
  position: relative;
}

.image-section h3::after, .text-section h3::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 80px;
  height: 2px;
  background-color: #42b883;
}

.image-preview {
  width: 100%;
  height: 320px;
  border: 1px solid #e0e6ed;
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 20px;
  background-color: #f8fafc;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
  position: relative;
  transition: all 0.3s ease;
}

.image-preview:hover {
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.image-preview img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.image-info {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(66, 184, 131, 0.85);
  color: white;
  padding: 10px 16px;
  font-size: 15px;
  font-weight: 500;
  text-align: center;
  letter-spacing: 0.5px;
  backdrop-filter: blur(2px);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.image-upload {
  width: 100%;
  height: 320px;
  border: 2px dashed #42b883;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
  background-color: #f0f9f5;
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.image-upload::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(135deg, rgba(66, 184, 131, 0.05) 0%, rgba(66, 184, 131, 0.01) 100%);
  z-index: 0;
}

.image-upload:hover {
  border-color: #3aa876;
  background-color: #e6f7f1;
  transform: translateY(-2px);
  cursor: pointer;
}

.upload-placeholder {
  color: #42b883;
  text-align: center;
  padding: 20px;
  font-size: 16px;
  font-weight: 500;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
  position: relative;
  z-index: 1;
}

.upload-icon {
  font-size: 56px;
  margin-bottom: 20px;
  opacity: 0.8;
  color: #42b883;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.upload-title {
  font-size: 18px;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 10px;
  line-height: 1.4;
}

.upload-hint {
  color: #666;
  font-size: 15px;
  margin-top: 10px;
  font-weight: normal;
}

.image-controls {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}

.image-controls input[type="file"] {
  display: none;
}

.text-section textarea {
  width: 100%;
  height: 270px;
  padding: 18px 20px;
  border: 1px solid #e0e6ed;
  border-radius: 8px;
  resize: none;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  font-size: 16px;
  line-height: 1.7;
  transition: all 0.3s ease;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05);
  color: #2c3e50;
  letter-spacing: 0.3px;
  background-color: #ffffff;
}

.text-section textarea:focus {
  outline: none;
  border-color: #42b883;
  box-shadow: 0 0 0 3px rgba(66, 184, 131, 0.2);
  background-color: #fcfcfc;
}

.text-section textarea::placeholder {
  color: #8492a6;
  font-size: 14px;
  opacity: 0.7;
}

.btn {
  padding: 12px 20px;
  background-color: #f5f7fa;
  border: 1px solid #e0e6ed;
  border-radius: 6px;
  cursor: pointer;
  font-size: 15px;
  font-weight: 500;
  transition: all 0.2s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: 150px;
  color: #2c3e50;
}

.btn-icon {
  font-size: 20px;
  display: inline-block;
}

.loading-spinner {
  display: inline-block;
  width: 24px;
  height: 24px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top-color: white;
  animation: spin 1s ease-in-out infinite;
}

.btn:hover {
  background-color: #e0e0e0;
  transform: translateY(-2px);
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
}

.btn.primary {
  background-color: #42b883;
  color: white;
  font-weight: 600;
  padding: 14px 28px;
  font-size: 16px;
  min-width: 180px;
  border: none;
  box-shadow: 0 4px 8px rgba(66, 184, 131, 0.25);
}

.btn.primary:hover {
  background-color: #3aa876;
  box-shadow: 0 4px 8px rgba(66, 184, 131, 0.25);
}

.btn:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
  opacity: 0.7;
}

.loading-spinner {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top-color: white;
  animation: spin 1s ease-in-out infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.action-section {
  margin: 40px 0;
  text-align: center;
}

.message-container {
  margin-top: 20px;
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

.message-icon {
  display: inline-block;
  margin-right: 10px;
  font-size: 18px;
}

.error {
  color: #e74c3c;
  margin-top: 15px;
  font-size: 16px;
  background-color: #fdecea;
  padding: 14px 18px;
  border-radius: 8px;
  border-left: 4px solid #e74c3c;
  font-weight: 500;
  display: flex;
  align-items: center;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.warning {
  color: #f39c12;
  margin-top: 15px;
  font-size: 16px;
  background-color: #fef5e7;
  padding: 14px 18px;
  border-radius: 8px;
  border-left: 4px solid #f39c12;
  font-weight: 500;
  display: flex;
  align-items: center;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.info {
  color: #3498db;
  margin-top: 15px;
  font-size: 16px;
  background-color: #eaf2fa;
  padding: 14px 18px;
  border-radius: 8px;
  border-left: 4px solid #3498db;
  font-weight: 500;
  display: flex;
  align-items: center;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.info-icon {
  color: #42b883;
}

.text-hint {
  color: #555;
  font-size: 15px;
  margin-top: 12px;
  padding: 10px 15px;
  background-color: #f0f9f5;
  border-radius: 6px;
  display: flex;
  align-items: center;
}

.result-section {
  border: 1px solid #e0e6ed;
  border-radius: 12px;
  padding: 30px 35px;
  background-color: #f8fafc;
  margin-top: 40px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
}

.result-section h3 {
  font-size: 22px;
  color: #2c3e50;
  margin-top: 0;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 2px solid #42b883;
  font-weight: 600;
}

.result-content {
  max-height: 600px;
  overflow-y: auto;
  background-color: #fff;
  padding: 25px 30px;
  border-radius: 10px;
  border: 1px solid #e0e6ed;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}

.response-text {
  margin-bottom: 25px;
  padding: 20px 25px;
  background-color: #f0f9f5;
  border-radius: 10px;
  border-left: 5px solid #42b883;
  box-shadow: 0 4px 12px rgba(66, 184, 131, 0.1);
  transition: all 0.3s ease;
}

.response-text:hover {
  box-shadow: 0 6px 16px rgba(66, 184, 131, 0.15);
  transform: translateY(-2px);
}

.result-icon {
  display: inline-block;
  margin-right: 12px;
  font-size: 24px;
  vertical-align: middle;
}

.response-text h4 {
  margin-top: 0;
  color: #2c3e50;
  margin-bottom: 20px;
  font-size: 20px;
  font-weight: 600;
  display: flex;
  align-items: center;
}

.response-text p {
  margin: 0;
  line-height: 1.8;
  white-space: pre-line;
  font-size: 16px;
  color: #2c3e50;
  padding: 18px 22px;
  background-color: rgba(255, 255, 255, 0.8);
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  letter-spacing: 0.3px;
}

.markdown-content {
  line-height: 1.7;
  color: #2c3e50;
  font-size: 16px;
  overflow-wrap: break-word;
}

.markdown-content h1,
.markdown-content h2,
.markdown-content h3,
.markdown-content h4,
.markdown-content h5,
.markdown-content h6 {
  margin-top: 24px;
  margin-bottom: 16px;
  font-weight: 600;
  line-height: 1.25;
}

.markdown-content h1 {
  font-size: 2em;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 0.3em;
}

.markdown-content h2 {
  font-size: 1.5em;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 0.3em;
}

.markdown-content h3 {
  font-size: 1.25em;
}

.markdown-content h4 {
  font-size: 1em;
}

.markdown-content p {
  margin-top: 0;
  margin-bottom: 16px;
}

.markdown-content blockquote {
  padding: 0 1em;
  color: #6a737d;
  border-left: 0.25em solid #dfe2e5;
  margin: 0 0 16px 0;
}

.markdown-content ul,
.markdown-content ol {
  padding-left: 2em;
  margin-top: 0;
  margin-bottom: 16px;
}

.markdown-content code {
  padding: 0.2em 0.4em;
  margin: 0;
  font-size: 85%;
  background-color: rgba(27, 31, 35, 0.05);
  border-radius: 3px;
  font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
}

.markdown-content pre {
  padding: 16px;
  overflow: auto;
  font-size: 85%;
  line-height: 1.45;
  background-color: #f6f8fa;
  border-radius: 3px;
  margin-top: 0;
  margin-bottom: 16px;
  word-wrap: normal;
}

.markdown-content pre code {
  background-color: transparent;
  padding: 0;
  margin: 0;
  font-size: 100%;
  word-break: normal;
  white-space: pre;
  overflow: visible;
}

.markdown-content img {
  max-width: 100%;
  box-sizing: content-box;
  background-color: #fff;
  border-radius: 3px;
}

.markdown-content table {
  border-spacing: 0;
  border-collapse: collapse;
  margin-top: 0;
  margin-bottom: 16px;
  width: 100%;
  overflow: auto;
}

.markdown-content table th {
  font-weight: 600;
  padding: 6px 13px;
  border: 1px solid #dfe2e5;
}

.markdown-content table td {
  padding: 6px 13px;
  border: 1px solid #dfe2e5;
}

.markdown-content table tr {
  background-color: #fff;
  border-top: 1px solid #c6cbd1;
}

.markdown-content table tr:nth-child(2n) {
  background-color: #f6f8fa;
}

.response-details {
  margin-top: 30px;
  background-color: #f8f8f8;
  border-radius: 10px;
  padding: 0;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08);
  overflow: hidden;
}

.response-details h4 {
  margin-top: 0;
  color: #2c3e50;
  margin-bottom: 0;
  border-bottom: 1px solid #e0e0e0;
  padding: 15px 20px;
  font-size: 20px;
  font-weight: 600;
  background-color: #f0f0f0;
  border-radius: 10px 10px 0 0;
  display: flex;
  align-items: center;
}

.json-toggle {
  position: relative;
  background-color: #f8f8f8;
  border-radius: 0 0 8px 8px;
  overflow: hidden;
  transition: all 0.3s ease;
}

pre {
  white-space: pre-wrap;
  word-wrap: break-word;
  margin: 0;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 14px;
  line-height: 1.6;
  background-color: #f8f8f8;
  padding: 15px;
  border-radius: 6px;
  border: 1px solid #eee;
  overflow-x: auto;
  color: #333;
}

::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 10px;
}

::-webkit-scrollbar-thumb {
  background: #42b883;
  border-radius: 10px;
}

::-webkit-scrollbar-thumb:hover {
  background: #3aa876;
}
</style>